package com.teach.config;

import com.teach.R;
import com.teach.annotation.IgnoreResponse;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

import org.jetbrains.annotations.NotNull;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * <pre>
 * -
 * Author : J.L.Zhou
 * E-Mail : 2233875735@qq.com
 * Tel : 151 1104 7708
 * Date : 2022-07-04 14:30
 * Version : 1.0
 * Copyright 2022 jlzhou.top Inc. All rights reserved.
 * Warning: this content is only for internal circulation of the company.
 *          It is forbidden to divulge it or use it for other commercial purposes.
 * </pre>
 **/
@RestControllerAdvice
@Slf4j
public class CommonResponseBodyAdvice implements ResponseBodyAdvice<Object> {

  @Override
  public boolean supports(@NotNull MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    
    Method method = returnType.getMethod();
    if (method==null || method.isAnnotationPresent(IgnoreResponse.class)) {
      return false;
    }
    return true;
  }

  /* 
   * 将Restful-api中方法的返回值使用R对象包装
   * @see org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice#beforeBodyWrite(java.lang.Object, org.springframework.core.MethodParameter, org.springframework.http.MediaType, java.lang.Class, org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse)
   */
  @Override
  public Object beforeBodyWrite(@Nullable Object body, MethodParameter returnType, MediaType selectedContentType,
      Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
      ServerHttpResponse response) {
        if (log.isTraceEnabled()) {
          log.trace("body:{}", body);
          log.trace("returnType:{}", returnType.getParameterType().getName());
          log.trace("selectedContentType:{},{},{}", selectedContentType.getType(), selectedContentType.getSubtype(),
              selectedContentType.getCharset());
          log.trace("selectedConverterType:{}", selectedConverterType.getName());
        }
        if ("json".equals(selectedContentType.getSubtype())) {
          if (null == body) {
            return R.ok();
          } else if (body instanceof R) {
            return body;
          } else {
            return R.ok().setData(body);
          }
        } else {
          return body;
        }
  }

}
